home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / nbtest.zip / NBTEST.C < prev    next >
C/C++ Source or Header  |  1992-04-03  |  13KB  |  529 lines

  1. /*
  2.  * minimal NetBIOS test program
  3.  * Copyright (C) 1987 Micro-Matic Research
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <dos.h>
  9. #include "nbtest.h"
  10.  
  11. #define FALSE           0
  12. #define TRUE            1
  13.  
  14. #define SENDNAME        "NBTEST-S"
  15. #define RECEIVENAME     "NBTEST-R"
  16. #define MAXBLKSIZE      16384
  17. #define MAXNCBS         20
  18.  
  19. NCB ncb;
  20. char sbuffer[MAXBLKSIZE+1];
  21. char rbuffer[MAXBLKSIZE+1];
  22.  
  23. int nrblocks = 200;
  24. int blksize = 1024;
  25. int bflag = 0;
  26. int iflag = FALSE;
  27. int vflag = FALSE;
  28. int wflag = FALSE;
  29.  
  30. /* Ascii error code table */
  31.  
  32. char *nb_err_tab[] =
  33.     {
  34.     "GOOD RETURN",
  35.     "ILLEGAL BUFFER LENGTH",
  36.     "UNDEFINED",
  37.     "INVALID COMMAND CODE",
  38.     "UNDEFINED",
  39.     "COMMAND TIMED OUT",
  40.     "MESSAGE INCOMPLETE (NOT ERR)",
  41.     "UNDEFINED",
  42.     "ILLEGAL LOCAL SESSION NUMBER",
  43.     "NO RESOURCE AVAILABLE",
  44.     "SESSION CLOSED",
  45.     "COMMAND CANCELLED",
  46.     "UNDEFINED",
  47.     "DUPLICATE NAME IN LOCAL NAME TABLE",
  48.     "NAME TABLE FULL",
  49.     "NAME HAS ACTIVE SESSION",
  50.     "UNDEFINED",
  51.     "LOCAL SESSION TABLE FULL",
  52.     "SESSION OPEN REJECTED",
  53.     "ILLEGAL NAMES NUMBER",
  54.     "COULDN'T FIND CALLED NAME",
  55.     "NAME NOT FOUND OR INVALID",
  56.     "NAME IN USE",
  57.     "NAME DELETED",
  58.     "SESSION ENDED ABNORMALLY",
  59.     "NAME CONFLICT DETECTED",
  60.     "INCOMPATIBLE REMOTE DEVICE",
  61.     "UNDEFINED",
  62.     "UNDEFINED",
  63.     "UNDEFINED",
  64.     "UNDEFINED",
  65.     "UNDEFINED",
  66.     "UNDEFINED",
  67.     "INTERFACE BUSY",
  68.     "TOO MANY COMMANDS OUTSTANDING",
  69.     "INVALID LANA_NUM VALUE",
  70.     "COMMAND NOT CANCELLED",
  71.     "RESERVED NAME SPECIFIED",
  72.     "COMMAND NOT VALID TO CANCEL"
  73.     };
  74.  
  75. void receive (void), send (void);
  76. void err (int);
  77. int nbexec (NCB *), nbsubmit (NCB *);
  78.  
  79. main (argc, argv)
  80. int argc;
  81. char *argv[];
  82.     {
  83.     int errcode;
  84.     int i;
  85.  
  86.     for (i = 1; i < argc; i++)
  87.         {
  88.         if (*argv[i] != '-')
  89.             goto usage;
  90.  
  91.         switch (*++argv[i])
  92.             {
  93.             case 'b':
  94.                 /* increment nr of simultaneous NCBs in background for TX/RX */
  95.                 if (++i >= argc)
  96.                     goto usage;
  97.                 bflag = atoi (argv[i]);
  98.                 break;
  99.             case 'n':
  100.                 /* specify number of blocks to send */
  101.                 if (++i >= argc)
  102.                     goto usage;
  103.                 nrblocks = atoi (argv[i]);
  104.                 break;
  105.             case 's':
  106.                 /* specify size of blocks to send */
  107.                 if (++i >= argc)
  108.                     goto usage;
  109.                 blksize = atoi (argv[i]);
  110.                 break;
  111.             case 'i':
  112.                 /* information about bytes transferred displayed */
  113.                 iflag = TRUE;
  114.                 break;
  115.             case 'w':
  116.                 /* wait for key before sending */
  117.                 wflag = iflag = TRUE;
  118.                 break;
  119.             case 'v':
  120.                 /* verify received data */
  121.                 vflag = TRUE;
  122.                 break;
  123.             default:
  124.                 goto usage;
  125.             }
  126.         }
  127.  
  128.     if (nrblocks < 1 || nrblocks > 10000 ||
  129.         blksize < 1 || blksize > MAXBLKSIZE ||
  130.         bflag < 0 || bflag > MAXNCBS)
  131.         goto usage;
  132.  
  133.     /* prime send buffer with cyclic bytes 0..255 */
  134.     for (i = 0; i < blksize; i++)
  135.         sbuffer[i] = i;
  136.  
  137.     printf ("\nNo-Wait option: %s\n", bflag ? "ON" : "OFF");
  138.     if (bflag)
  139.         printf ("%d NCB%s issued simultaneously\n", bflag,
  140.                 (bflag == 1) ? " is" : "s are");
  141.  
  142.     /* try to act as the receiver first */
  143.  
  144.     printf ("\nTrying to register name '%s'\n", RECEIVENAME);
  145.     memset (&ncb, 0, sizeof (ncb));
  146.     ncb.ncb_command = N_ADDNAME;
  147.     strncpy (ncb.ncb_name, RECEIVENAME, 16);
  148.  
  149.     if ((errcode = nbexec (&ncb)) == 0)
  150.         {
  151.         receive();
  152.         exit (0);
  153.         }
  154.  
  155.     if (errcode == 0x16)
  156.         printf ("--> NAME IN USE\n");
  157.     else
  158.         err (errcode);
  159.  
  160.     /* if we cannot be receiver we'll have to be sender */
  161.  
  162.     printf ("\nTrying to register name '%s'\n", SENDNAME);
  163.     memset (&ncb, 0, sizeof (ncb));
  164.     ncb.ncb_command = N_ADDNAME;
  165.     strncpy (ncb.ncb_name, SENDNAME, 16);
  166.  
  167.     if ((errcode = nbexec (&ncb)) == 0)
  168.         {
  169.         send();
  170.         exit (0);
  171.         }
  172.  
  173.     err (errcode);
  174.     exit (0);
  175.  
  176. usage:
  177.     printf ("Usage:\n");
  178.     printf ("nbtest [-i] [-b oc] [-n nr_blocks] [-s size_blocks]\n");
  179.     printf ("    -i         interactive; updates bytes exchanged\n");
  180.     printf ("    -w         wait for key before sending each packet\n");
  181.     printf ("    -v         verify received data length and data\n");
  182.     printf ("    -b nnn     number of commands sent in NO-WAIT mode (0..%d)\n",
  183.             MAXNCBS);
  184.     printf ("    -n nnn     number of blocks exchanged (1..10000)\n");
  185.     printf ("    -s nnn     size of blocks (1..16384)\n",
  186.             MAXBLKSIZE);
  187.     printf ("Default: -b 0 -n 200 -s 1024\n");
  188.     exit (1);
  189.     }
  190.  
  191.  
  192. void send (void)
  193.     {
  194.     int errcode;
  195.     long starttime, endtime;
  196.     unsigned long byte = 0;
  197.     unsigned long kbyte = 0;
  198.     int etime;
  199.     int i;
  200.     BYTE lsn;
  201.  
  202. call:
  203.     printf ("\nCalling '%s'\n", RECEIVENAME);
  204.     fflush (stdout);
  205.  
  206.     memset (&ncb, 0, sizeof (ncb));
  207.     ncb.ncb_command = N_CALL;
  208.     strncpy (ncb.ncb_name,     SENDNAME,    16);
  209.     strncpy (ncb.ncb_callname, RECEIVENAME, 16);
  210.     ncb.ncb_rto = 20;
  211.     ncb.ncb_sto = 20;
  212.  
  213.     if ((errcode = nbexec (&ncb)) != 0)
  214.         {
  215.         err (errcode);
  216.         goto deregister;
  217.         }
  218.  
  219.     printf ("-> Session established with '%s' as #%d\n",
  220.             RECEIVENAME, ncb.ncb_lsn);
  221.     fflush (stdout);
  222.  
  223.     lsn = ncb.ncb_lsn;
  224.  
  225. transfer:
  226.     printf ("\nStarting transfer of %d blocks of %d bytes\n",
  227.             nrblocks, blksize);
  228.     printf ("-> KB transferred:       ");
  229.     fflush (stdout);
  230.  
  231.     time (&starttime);
  232.  
  233.  
  234.     for (i = 0; i < nrblocks; i += (bflag ? bflag : 1))
  235.         {
  236.         if (wflag)
  237.             getch ();
  238.  
  239.         memset (&ncb, 0, sizeof (ncb));
  240.  
  241.         ncb.ncb_command = N_SEND;
  242.         ncb.ncb_lsn = lsn;
  243.         ncb.ncb_buffer = (BYTE _far *) sbuffer;
  244.         ncb.ncb_length = blksize;
  245.  
  246.         if ((errcode = nbsubmit (&ncb)) != 0)
  247.             break;
  248.  
  249.         byte += bflag ? (long)blksize*bflag : blksize;
  250.  
  251.         if (byte > kbyte * 1024L)
  252.             {
  253.             while (byte > kbyte * 1024L)
  254.                 kbyte++;
  255.  
  256.             if (iflag)
  257.                 {
  258.                 printf ("\b\b\b\b\b\b%-6ld", kbyte);
  259.                 fflush (stdout);
  260.                 }
  261.             }
  262.         }
  263.  
  264.     printf ("\b\b\b\b\b\b%-6ld\n", kbyte);
  265.     fflush (stdout);
  266.  
  267.     time (&endtime);
  268.     etime = endtime - starttime;
  269.  
  270.     if (errcode != 0)
  271.         err (errcode);
  272.  
  273.     printf ("-> Data transfer completed.\n");
  274.     printf ("-> Time elapsed: %d seconds\n", etime);
  275.     printf ("-> Blocks transferred: %d\n", i);
  276.  
  277.     if (etime >= 3 && kbyte > 0 && (kbyte / etime) > 0)
  278.         printf ("-> Transfer rate: %d KB/sec\n", (int)(kbyte / etime));
  279.     else
  280.         printf ("-> Transfer rate not determined\n");
  281.  
  282. hangup:
  283.     printf ("\nHanging up\n");
  284.     fflush (stdout);
  285.  
  286.     memset (&ncb, 0, sizeof (ncb));
  287.     ncb.ncb_command = N_HANGUP;
  288.     ncb.ncb_lsn = lsn;
  289.     if ((errcode = nbexec (&ncb)) != 0 && errcode != E_SES_CLOSE)
  290.         {
  291.         err (errcode);
  292.         goto deregister;
  293.         }
  294.  
  295.     printf ("-> Session with '%s' closed\n", RECEIVENAME);
  296.  
  297. deregister:
  298.     printf ("\nDeregistering name '%s'\n", SENDNAME);
  299.     fflush (stdout);
  300.  
  301.     memset (&ncb, 0, sizeof (ncb));
  302.     ncb.ncb_command = N_DELETENAME;
  303.     strncpy (ncb.ncb_name, SENDNAME, 16);
  304.     if ((errcode = nbexec (&ncb)) != 0)
  305.         {
  306.         err (errcode);
  307.         return;
  308.         }
  309.  
  310.     printf ("-> Name deregistered\n");
  311.     return;
  312.     }
  313.  
  314.  
  315. void receive (void)
  316.     {
  317.     int errcode;
  318.     long starttime, endtime;
  319.     unsigned long kbyte = 0;
  320.     unsigned long byte = 0;
  321.     int etime;
  322.     int i;
  323.     BYTE lsn;
  324.  
  325. listen:
  326.     printf ("\nWaiting for a call from '%s'\n", SENDNAME);
  327.     fflush (stdout);
  328.  
  329.     memset (&ncb, 0, sizeof (ncb));
  330.     ncb.ncb_command = N_LISTEN;
  331.     strncpy (ncb.ncb_name,     RECEIVENAME, 16);
  332.     strncpy (ncb.ncb_callname, SENDNAME,    16);
  333.     ncb.ncb_rto = 20;
  334.     ncb.ncb_sto = 20;
  335.  
  336.     if ((errcode = nbexec (&ncb)) != 0)
  337.         {
  338.         err (errcode);
  339.         goto deregister;
  340.         }
  341.  
  342.     printf ("-> Session established with '%s' as #%d\n",
  343.             SENDNAME, ncb.ncb_lsn);
  344.     fflush (stdout);
  345.  
  346.     lsn = ncb.ncb_lsn;
  347.  
  348. transfer:
  349.     printf ("\nReception of %d blocks of %d bytes in progress\n",
  350.             nrblocks, blksize);
  351.     printf ("-> KB transferred:       ");
  352.     fflush (stdout);
  353.  
  354.     time (&starttime);
  355.  
  356.  
  357.     for (i = 0; i < nrblocks; i += (bflag ? bflag : 1))
  358.         {
  359.         memset (&ncb, 0, sizeof (ncb));
  360.  
  361.         ncb.ncb_command = N_RECEIVE;
  362.         ncb.ncb_lsn = lsn;
  363.         ncb.ncb_buffer = (BYTE _far *) rbuffer;
  364.         ncb.ncb_length = blksize;
  365.  
  366.         if ((errcode = nbsubmit (&ncb)) != 0)
  367.             break;
  368.  
  369.         if (vflag)
  370.             {
  371.             if (ncb.ncb_length != blksize)
  372.                 {
  373.                 printf ("\n-> Received length mismatch; expected=%d actual=%d\n",
  374.                     blksize, ncb.ncb_length);
  375.                 fflush (stdout);
  376.                 break;
  377.                 }
  378.             if (memcmp (sbuffer, rbuffer, blksize) != 0)
  379.                 {
  380.                 printf ("\n-> Received data miscompare\n");
  381.                 fflush (stdout);
  382.                 break;
  383.                 }
  384.             }
  385.  
  386.         byte += bflag ? (long)blksize*bflag : blksize;
  387.  
  388.         if (byte > kbyte * 1024L)
  389.             {
  390.             while (byte > kbyte * 1024L)
  391.                 kbyte++;
  392.  
  393.             if (iflag)
  394.                 {
  395.                 printf ("\b\b\b\b\b\b%-6ld", kbyte);
  396.                 fflush (stdout);
  397.                 }
  398.             }
  399.         }
  400.  
  401.     printf ("\b\b\b\b\b\b%-6ld\n", kbyte);
  402.     fflush (stdout);
  403.  
  404.     time (&endtime);
  405.     etime = endtime - starttime;
  406.  
  407.     if (errcode != 0)
  408.         err (errcode);
  409.  
  410.     printf ("-> Data transfer completed.\n");
  411.     printf ("-> Time elapsed: %d seconds\n", etime);
  412.     printf ("-> Blocks transferred: %d\n", i);
  413.  
  414.     if (etime >= 3 && kbyte > 0 && (kbyte / etime) > 0)
  415.         printf ("-> Transfer rate: %d KB/sec\n", (int)(kbyte / etime));
  416.     else
  417.         printf ("-> Transfer rate not determined\n");
  418.  
  419. hangup:
  420.     printf ("\nHanging up\n");
  421.     fflush (stdout);
  422.  
  423.     memset (&ncb, 0, sizeof (ncb));
  424.     ncb.ncb_command = N_HANGUP;
  425.     ncb.ncb_lsn = lsn;
  426.     if ((errcode = nbexec (&ncb)) != 0 && errcode != E_SES_CLOSE)
  427.         {
  428.         err (errcode);
  429.         goto deregister;
  430.         }
  431.  
  432.     printf ("-> Session with '%s' closed\n", RECEIVENAME);
  433.  
  434. deregister:
  435.     printf ("\nDeregistering name '%s'\n", RECEIVENAME);
  436.     fflush (stdout);
  437.  
  438.     ncb.ncb_command = N_DELETENAME;
  439.     strncpy (ncb.ncb_name, RECEIVENAME, 16);
  440.     if ((errcode = nbexec (&ncb)) != 0)
  441.         {
  442.         err (errcode);
  443.         return;
  444.         }
  445.  
  446.     printf ("-> Name deregistered\n");
  447.  
  448.     return;
  449.     }
  450.  
  451.  
  452. void err (code)
  453. int code;
  454.     {
  455.     printf ("-> ERROR: code = 0x%x", code);
  456.     if (code < (sizeof (nb_err_tab) / sizeof (*nb_err_tab)))
  457.         printf (" (%s)", nb_err_tab[code]);
  458.     printf ("\n");
  459.     }
  460.  
  461. static volatile int bg_nberr;
  462. static volatile int bg_num;
  463. static NCB bg_ncbs[MAXNCBS+1];
  464.  
  465. #pragma check_stack-
  466.  
  467. void _interrupt _far nbpost (es, ds, di, si, bp, sp, bx)
  468. unsigned short es, ds, di, si, bp, sp, bx;
  469.     {
  470.     NCB _far *pncb;
  471.  
  472.     FP_OFF (pncb) = bx;
  473.     FP_SEG (pncb) = es;
  474.  
  475.     --bg_num;
  476.     bg_nberr = pncb->ncb_cmd_cplt;
  477.     }
  478.  
  479. #pragma check_stack+
  480.  
  481. int nbexec (NCB *pncb)
  482.     {
  483.     union REGS regs;
  484.     struct SREGS sregs;
  485.     char far *fptr = (char far *) pncb;
  486.  
  487.     regs.x.bx = FP_OFF (fptr);
  488.     sregs.es = FP_SEG (fptr);
  489.     int86x (0x5C, ®s, ®s, &sregs);
  490.     return (pncb->ncb_retcode);
  491.     }
  492.  
  493. /* execute the ncb in foreground or background */
  494.  
  495. int nbsubmit (pncb)
  496. NCB *pncb;
  497.     {
  498.     int errcode;
  499.     int i;
  500.  
  501.     /* execute directly if wait mode */
  502.     if (bflag == 0)
  503.         {
  504.         pncb->ncb_post = NULL;
  505.         return (nbexec (pncb));
  506.         }
  507.  
  508.     bg_nberr = -1;
  509.     bg_num = bflag;
  510.  
  511.     pncb->ncb_command |= N_NOWAIT;
  512.     pncb->ncb_post = nbpost;
  513.  
  514.     /* issue bflag copies of the NCB in nowait mode */
  515.     for (i = 0; i < bflag; ++i)
  516.         {
  517.         bg_ncbs[i] = *pncb;
  518.         if ((errcode = nbexec (&bg_ncbs[i])) != 0 && errcode != 0xFF)
  519.             return (errcode);
  520.         }
  521.  
  522.     /* wait till all completed */
  523.     while (bg_num > 0)
  524.         if (bg_nberr != -1 && bg_nberr != 0)
  525.             return (bg_nberr);
  526.  
  527.     return (0);
  528.     }
  529.